from midi.midi_message import MidiMessage
from midi.serializable import Serializable

class MidiEvent(Serializable):
    __tick: int # 时间
    __message: MidiMessage # 消息

    def __init__(self, tick: int, message: MidiMessage) -> None:
        self.__tick = tick
        self.__message = message
    
    def getTick(self) -> int:
        return self.__tick
    
    def getMessage(self) -> MidiMessage:
        return self.__message
    
    def hex(self, datum_time) -> str:
        bin_tick = bin(self.__tick-datum_time)[2:]
        bin_tick_length = len(bin_tick)
        if bin_tick_length <= 7:
            hex_tick = hex(int("0"+"0"*(7-bin_tick_length)+bin_tick, 2))[2:]
            hex_tick = "0"*(2-len(hex_tick))+hex_tick
        elif bin_tick_length > 28:
            raise ValueError("delta time is too big")
        else:
            times = len(bin_tick)%7
            if times == 0:
                times = len(bin_tick)//7
            else:
                times = len(bin_tick)//7+1
                bin_tick = "0"*(times*7-len(bin_tick))+bin_tick
            encode_bin_tick = ""
            for i in range(0, times):
                if i == 0:
                    encode_bin_tick = "0"+bin_tick[-1*(i+1)*7:][:7]+encode_bin_tick
                else:
                    encode_bin_tick = "1"+bin_tick[-1*(i+1)*7:][:7]+encode_bin_tick
            hex_tick = hex(int(encode_bin_tick, 2))[2:]
        return hex_tick+self.getMessage().hex()